﻿using Hangfire.States;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Hangfire.HttpJob.CSRedis.Middleware
{
    /// <summary>
    /// hangfire 远程作业回调中间件
    /// </summary>
    internal class CallBackMiddleware
    {
        readonly RequestDelegate _next;
        readonly ILogger<CallBackMiddleware> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public CallBackMiddleware(
            RequestDelegate next,
            ILogger<CallBackMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        /// <summary>
        /// invoke
        /// </summary>
        public async Task InvokeAsync(HttpContext context)
        {
            context.Request.EnableBuffering();
            context.Request.Body.Seek(0, SeekOrigin.Begin);
            using (var reader = new StreamReader(context.Request.Body))
            {
                var content = await reader.ReadToEndAsync();
                if (!string.IsNullOrWhiteSpace(content))
                {
                    try
                    {
                        var callbackData = JsonConvert.DeserializeObject<CallBackData>(content);
                        if (!string.IsNullOrWhiteSpace(callbackData?.JobId))
                        {
                            var bjc = context.RequestServices.GetService<IBackgroundJobClient>();
                            JobStorage.Current.GetConnection().SetJobParameter(callbackData.JobId, "最终状态", "远程作业执行完成");
                            if (callbackData.IsSuccess)
                                bjc.ChangeState(callbackData.JobId, new SucceededState(callbackData.Result, 0, callbackData.Duration));
                            else
                                bjc.ChangeState(callbackData.JobId, new FailedState(new Exception(callbackData.Result)));
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.LogError("异常:{0}", e);
                    }
                }
            }
        }
    }
}
